home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / 1750a / 1750a.c next >
C/C++ Source or Header  |  1994-09-20  |  14KB  |  589 lines

  1. /* Subroutines for insn-output.c for MIL-STD-1750.
  2.    Copyright (C) 1994 Free Software Foundation, Inc.
  3.    Contributed by O.M.Kellogg, DASA (okellogg@salyko.cube.net).
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #ifndef FILE
  22. #include <stdio.h>
  23. #endif
  24.  
  25. #define __datalbl
  26. #include "config.h"
  27. #include "rtl.h"
  28. #include "tree.h"
  29. #include "expr.h"
  30. #define HAVE_cc0
  31. #include "conditions.h"
  32. #include "real.h"
  33.  
  34. struct datalabel_array datalbl[DATALBL_ARRSIZ];
  35. int datalbl_ndx = -1;
  36. struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
  37. int jmplbl_ndx = -1;
  38. int label_pending = 0, program_counter = 0;
  39. enum section current_section = Normal;
  40. char *sectname[4] =
  41. {"Normal", "Init", "Konst", "Static"};
  42.  
  43. int
  44. notice_update_cc (exp)
  45.      rtx exp;
  46. {
  47.   if (GET_CODE (exp) == SET)
  48.     {
  49.       enum rtx_code src_code = GET_CODE (SET_SRC (exp));
  50.       /* Jumps do not alter the cc's.  */
  51.       if (SET_DEST (exp) == pc_rtx)
  52.     return;
  53.       /* Moving register into memory doesn't alter the cc's.
  54.      It may invalidate the RTX's which we remember the cc's came from.  */
  55.       if (GET_CODE (SET_DEST (exp)) == MEM)
  56.     {
  57.       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
  58.         cc_status.value1 = 0;
  59.       if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
  60.         cc_status.value2 = 0;
  61.       return;
  62.     }
  63.       /* Function calls clobber the cc's.  */
  64.       else if (src_code == CALL)
  65.     {
  66.       CC_STATUS_INIT;
  67.       return;
  68.     }
  69.       /* Emulated longword bit-ops leave cc's incorrect */
  70.       else if (GET_MODE (SET_DEST (exp)) == HImode ?
  71.            src_code == AND || src_code == IOR ||
  72.            src_code == XOR || src_code == NOT : 0)
  73.     {
  74.       CC_STATUS_INIT;
  75.       return;
  76.     }
  77.       /* Tests and compares set the cc's in predictable ways.  */
  78.       else if (SET_DEST (exp) == cc0_rtx)
  79.     {
  80.       CC_STATUS_INIT;
  81.       cc_status.value1 = SET_SRC (exp);
  82.       return;
  83.     }
  84.       /* Anything that lands in a reg will set cc_status. */
  85.       else if (REG_P (SET_DEST (exp)))
  86.     {
  87.       cc_status.flags = CC_NO_OVERFLOW;
  88.       cc_status.value1 = SET_SRC (exp);
  89.       cc_status.value2 = SET_DEST (exp);
  90.       return;
  91.     }
  92.       else
  93.     {
  94.       CC_STATUS_INIT;
  95.     }
  96.     }
  97.   else if (GET_CODE (exp) == PARALLEL
  98.        && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
  99.     {
  100.       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
  101.     return;
  102.       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
  103.     {
  104.       CC_STATUS_INIT;
  105.       cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
  106.       return;
  107.     }
  108.       CC_STATUS_INIT;
  109.     }
  110.   else
  111.     {
  112.       CC_STATUS_INIT;
  113.     }
  114. }
  115.  
  116.  
  117. rtx
  118. function_arg (cum, mode, type, named)
  119.      int cum;
  120.      enum machine_mode mode;
  121.      tree type;
  122.      int named;
  123. {
  124.   int size;
  125.   rtx result;
  126.  
  127.   if (MUST_PASS_IN_STACK (mode, type))
  128.     return (rtx) 0;
  129.   if (mode == BLKmode)
  130.     size = int_size_in_bytes (type);
  131.   else
  132.     size = GET_MODE_SIZE (mode);
  133.   if (cum + size < 12)
  134.     return gen_rtx (REG, mode, cum);
  135.   else
  136.     return (rtx) 0;
  137. }
  138.  
  139.  
  140. #ifndef STRDUP
  141. char *
  142. strdup (str)
  143.      char *str;
  144. {
  145.   char *p;
  146.   if (str == NULL)
  147.     return NULL;
  148.   if ((p = (char *) malloc (strlen (str) + 1)) == NULL)
  149.     {
  150.       fprintf (stderr, "dynamic memory exhausted");
  151.       abort ();
  152.     }
  153.   return strcpy (p, str);
  154. }
  155.  
  156. #endif
  157.  
  158.  
  159. double
  160. get_double (x)
  161.      rtx x;
  162. {
  163.   union
  164.     {
  165.       double d;
  166.       long i[2];
  167.     }
  168.   du;
  169.  
  170.   du.i[0] = CONST_DOUBLE_LOW (x);
  171.   du.i[1] = CONST_DOUBLE_HIGH (x);
  172.   return du.d;
  173. }
  174.  
  175. char *
  176. float_label (code, value)
  177.      char code;
  178.      double value;
  179. {
  180.   int i = 1;
  181.   static char label[32];
  182.   char *p;
  183.  
  184.   label[0] = code;
  185.   p = label + 1;
  186.   sprintf (p, "%lf", value);
  187.   while (*p)
  188.     {
  189.       *p = (*p == '+') ? 'p' :
  190.     (*p == '-') ? 'm' : *p;
  191.       p++;
  192.     }
  193.   return strdup (label);
  194. }
  195.  
  196.  
  197. char *
  198. movcnt_regno_adjust (rtx * op)
  199. {
  200.   static char outstr[40];
  201.   int cntreg = REGNO (op[2]), cntreg_1750 = REGNO (op[0]) + 1;
  202.   int dstreg = REGNO (op[0]), srcreg = REGNO (op[1]);
  203.  
  204.   if (cntreg == cntreg_1750)
  205.     sprintf (outstr, "mov r%%0,r%%1");
  206.   else if (dstreg + 1 == srcreg && srcreg == cntreg + 2)
  207.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", cntreg, dstreg);
  208.   else if (dstreg + 1 == srcreg && srcreg < cntreg)
  209.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, cntreg);
  210.   else if (srcreg + 1 == cntreg && dstreg > cntreg)
  211.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, dstreg);
  212.   else
  213.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,%%1\n\txwr r%d,r%d",
  214.          cntreg, cntreg_1750, cntreg_1750, cntreg);
  215.   return outstr;
  216. }
  217.  
  218. char *
  219. mod_regno_adjust (char *instr, rtx * op)
  220. {
  221.   static char outstr[40];
  222.   char *r = (!strncmp (instr, "dvr", 3) ? "r" : "");
  223.   int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;
  224.  
  225.   if (modregno_gcc == modregno_1750)
  226.     sprintf (outstr, "%s r%%0,%s%%2", instr, r);
  227.   else
  228.     sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",
  229.     modregno_gcc, modregno_1750, instr, r, modregno_1750, modregno_gcc);
  230.   return outstr;
  231. }
  232.  
  233.  
  234. /* Auxiliary to `nonindirect_operand':
  235.    Check if op is a valid memory operand for 1750A arith./logic (non-move)
  236.    instructions. */
  237. int
  238. memop_valid (register rtx op)
  239. {
  240.   if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode)
  241.     return 0;
  242.   switch (GET_CODE (op))
  243.     {
  244.     case MEM:
  245.     case MINUS:
  246.     case MULT:
  247.     case DIV:
  248.       return 0;
  249.     case PLUS:
  250.       if (!memop_valid (XEXP (op, 0)))
  251.     return 0;
  252.       return memop_valid (XEXP (op, 1));
  253.     case REG:
  254.       if (REGNO (op) > 0)
  255.     return 1;
  256.       return 0;
  257.     case CONST:
  258.     case CONST_INT:
  259.     case SYMBOL_REF:
  260.     case SUBREG:
  261.       return 1;
  262.     default:
  263.       printf ("memop_valid: code=%d\n", (int) GET_CODE (op));
  264.       return 1;
  265.     }
  266. }
  267.  
  268. /* extra predicate for recog: */
  269. int
  270. nonindirect_operand (register rtx op, enum machine_mode mode)
  271. {
  272.   int retval;
  273.  
  274.   switch (GET_CODE (op))
  275.     {
  276.     case MEM:
  277.       retval = memop_valid (XEXP (op, 0));
  278.       return retval;
  279.     case REG:
  280.       return 1;
  281.     default:
  282.       if (!CONSTANT_P (op))
  283.     return 0;
  284.     }
  285.   return 1;
  286. }
  287.  
  288. /* predicate for the STC instruction: */
  289. int
  290. small_nonneg_const (register rtx op, enum machine_mode mode)
  291. {
  292.   if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)
  293.     return 1;
  294.   return 0;
  295. }
  296.  
  297. /* Decide whether to output a conditional jump as a "Jump Conditional"
  298.    or as a "Branch Conditional": */
  299.  
  300. int
  301. find_jmplbl (int labelnum)
  302. {
  303.   int i, found = 0;
  304.  
  305.   for (i = 0; i <= jmplbl_ndx; i++)
  306.     if (labelnum == jmplbl[i].num)
  307.       {
  308.     found = 1;
  309.     break;
  310.       }
  311.   if (found)
  312.     return i;
  313.   return -1;
  314. }
  315.  
  316. char *
  317. branch_or_jump (char *condition, int targetlabel_number)
  318. {
  319.   static char buf[30];
  320.   int index;
  321.  
  322.   if ((index = find_jmplbl (targetlabel_number)) >= 0)
  323.     if (program_counter - jmplbl[index].pc < 128)
  324.       {
  325.     sprintf (buf, "b%s %%l0", condition);
  326.     return buf;
  327.       }
  328.   sprintf (buf, "jc %s,%%l0", condition);
  329.   return buf;
  330. }
  331.  
  332.  
  333.  
  334. /* The PRINT_OPERAND and PRINT_OPERAND_ADDRESS macros have been
  335.    made functions: */
  336.  
  337. print_operand (file, x, kode)
  338.      FILE *file;
  339.      rtx x;
  340.      enum rtx_code kode;
  341. {
  342.   switch (GET_CODE (x))
  343.     {
  344.     case REG:
  345.       fprintf (file, "%d", REGNO (x));
  346.       break;
  347.     case SYMBOL_REF:
  348.       fprintf (file, "%s", XSTR (x, 0));
  349.       break;
  350.     case LABEL_REF:
  351.     case CONST:
  352.     case MEM:
  353.       output_address (XEXP (x, 0));
  354.       break;
  355.     case CONST_DOUBLE:
  356. /*    {
  357.     double value = get_double (x);
  358.     char fltstr[32];
  359.     sprintf (fltstr, "%lf", value);
  360.  
  361.     if (kode == 'D' || kode == 'E')
  362.       {
  363.         int i, found = 0;
  364.         for (i = 0; i <= datalbl_ndx; i++)
  365.           if (strcmp (fltstr, datalbl[i].value) == 0)
  366.         {
  367.           found = 1;
  368.           break;
  369.         }
  370.         if (!found)
  371.           {
  372.         strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
  373.         datalbl[i].name = float_label (kode, value);
  374.         datalbl[i].size = (kode == 'E') ? 3 : 2;
  375.         check_section (Konst);
  376.         fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
  377.             (kode == 'E' ? "ef" : "f"), fltstr);
  378.         check_section (Normal);
  379.           }
  380.       }
  381.     else if (kode == 'F' || kode == 'G')
  382.       {
  383.         int i, found = 0;
  384.         for (i = 0; i <= datalbl_ndx; i++)
  385.           if (strcmp (fltstr, datalbl[i].value) == 0)
  386.         {
  387.           found = 1;
  388.           break;
  389.         }
  390.         if (!found)
  391.           {
  392.         fprintf (stderr,
  393.            "float value %lfnot found upon label reference\n", value);
  394.         strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
  395.         datalbl[i].name = float_label (kode, value);
  396.         datalbl[i].size = (kode == 'G') ? 3 : 2;
  397.         check_section (Konst);
  398.         fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
  399.             (kode == 'G' ? "ef" : "f"), fltstr);
  400.         check_section (Normal);
  401.           }
  402.         fprintf (file, "%s ;P_O 'F'", datalbl[i].name);
  403.       }
  404.     else
  405.       fprintf (file, " %s  ;P_O cst_dbl ", fltstr);
  406.       }
  407.  */
  408.       fprintf (file, "%lf", get_double (x));
  409.       break;
  410.     case CONST_INT:
  411.       if (kode == 'J')
  412.     fprintf (file, "%d", -INTVAL (x));
  413.       else if (INTVAL (x) > 0x7FFF)
  414.     fprintf (file, "%d  ; range correction (val>0x7FFF) applied",
  415.          INTVAL (x) - 0x10000);
  416.       else
  417.     fprintf (file, "%d", INTVAL (x));
  418.       break;
  419.     case CODE_LABEL:
  420.       fprintf (file, "L%d", XINT (x, 3));
  421.       break;
  422.     case CALL:
  423.       fprintf (file, "CALL nargs=%d, func is either '%s' or '%s'",
  424.        XEXP (x, 1), XSTR (XEXP (XEXP (x, 0), 1), 0), XSTR (XEXP (x, 0), 1));
  425.       break;
  426.     case PLUS:
  427.       {
  428.     rtx op0 = XEXP (x, 0), op1 = XEXP (x, 1);
  429.     int op0code = GET_CODE (op0), op1code = GET_CODE (op1);
  430.     if (op1code == CONST_INT)
  431.       switch (op0code)
  432.         {
  433.         case REG:
  434.           fprintf (file, "%d,r%d  ; p_o_PLUS for REG and CONST",
  435.                INTVAL (op1), REGNO (op0));
  436.           break;
  437.         case SYMBOL_REF:
  438.           fprintf (file, "%d+%s", INTVAL (op1), XSTR (op0, 0));
  439.           break;
  440.         case MEM:
  441.           fprintf (file, "%d,[mem:", INTVAL (op1));
  442.           output_address (XEXP (op0, 0));
  443.           fprintf (file, "] ;P_O plus");
  444.           break;
  445.         default:
  446.           fprintf (file, "p_o_PLUS UFO, code=%d, with CONST=%d",
  447.                (int) op0code, INTVAL (op1));
  448.         }
  449.     else if (op1code == SYMBOL_REF && op0code == REG)
  450.       fprintf (file, "%s,r%d  ; P_O: (plus reg sym)",
  451.            XSTR (op1, 0), REGNO (op0));
  452.     else
  453.       fprintf (file, "p_o_+: op0code=%d, op1code=%d", op0code, op1code);
  454.       }
  455.       break;
  456.     default:
  457.       fprintf (file, "p_o_UFO code=%d", GET_CODE (x));
  458.     }
  459. }
  460.  
  461. print_operand_address (file, addr)
  462.      FILE *file;
  463.      rtx addr;
  464. {
  465.   switch (GET_CODE (addr))
  466.     {
  467.     case REG:
  468.       fprintf (file, "0,r%d ; P_O_A", REGNO (addr));
  469.       break;
  470.     case PLUS:
  471.       {
  472.     register rtx x = XEXP (addr, 0), y = XEXP (addr, 1);
  473.     switch (GET_CODE (x))
  474.       {
  475.       case REG:
  476.         switch (GET_CODE (y))
  477.           {
  478.           case CONST:
  479.         output_address (XEXP (y, 0));
  480.         fprintf (file, ",r%d ;P_O_A reg + const expr", REGNO (x));
  481.         break;
  482.           case CONST_INT:
  483.         fprintf (file, "%d,r%d", INTVAL (y), REGNO (x));
  484.         break;
  485.           case SYMBOL_REF:
  486.         fprintf (file, "%s,r%d  ; P_O_A reg + sym",
  487.              XSTR (y, 0), REGNO (x));
  488.         break;
  489.           default:
  490.         fprintf (file, "[P_O_A reg%d+UFO code=%d]",
  491.              REGNO (x), GET_CODE (y));
  492.           }
  493.         break;
  494.       case LABEL_REF:
  495.       case SYMBOL_REF:
  496.         switch (GET_CODE (y))
  497.           {
  498.           case CONST_INT:
  499.         fprintf (file, "%d+%s", INTVAL (y), XSTR (x, 0));
  500.         break;
  501.           case REG:
  502.         fprintf (file, "%s,r%d ;P_O_A sym + reg",
  503.              XSTR (x, 0), REGNO (y));
  504.         break;
  505.           default:
  506.         fprintf (file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
  507.              XSTR (x, 0), GET_CODE (y));
  508.           }
  509.         break;
  510.       case CONST:
  511.         output_address (XEXP (x, 0));
  512.         if (GET_CODE (y) == REG)
  513.           fprintf (file, ",r%d ;P_O_A const + reg", REGNO (x));
  514.         else
  515.           fprintf (file, "P_O_A const+UFO code(y)=%d]", GET_CODE (y));
  516.         break;
  517.       case MEM:
  518.         output_address (y);
  519.         fprintf (file, ",[mem:");
  520.         output_address (XEXP (x, 0));
  521.         fprintf (file, "] ;P_O_A plus");
  522.         break;
  523.       default:
  524.         fprintf (file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
  525.              GET_CODE (x), GET_CODE (y));
  526.       }
  527.       }
  528.       break;
  529.     case CONST_INT:
  530.       if (INTVAL (addr) < 0x10000 && INTVAL (addr) >= -0x10000)
  531.     fprintf (file, "%d ; p_o_a const addr?!", INTVAL (addr));
  532.       else
  533.     {
  534.       fprintf (file, "[p_o_a=ILLEGAL_CONST]");
  535.       output_addr_const (file, addr);
  536.     }
  537.       break;
  538.     case LABEL_REF:
  539.     case SYMBOL_REF:
  540.       fprintf (file, "%s", XSTR (addr, 0));
  541.       break;
  542.     case MEM:
  543.       fprintf (file, "[memUFO:");
  544.       output_address (XEXP (addr, 0));
  545.       fprintf (file, "]");
  546.       break;
  547.     case CONST:
  548.       output_address (XEXP (addr, 0));
  549.       fprintf (file, " ;P_O_A const");
  550.       break;
  551.     default:
  552.       fprintf (file, " p_o_a UFO, code=%d val=0x%x",
  553.            (int) GET_CODE (addr), INTVAL (addr));
  554.       break;
  555.     }
  556. }
  557.  
  558.  
  559. /*
  560. ASM_FILE_END(file)
  561.   FILE *file;
  562. {
  563.       if (datalbl_ndx >= 0) {
  564.          int i, cum_size=0;
  565.          fprintf(file,"\n\tstatic\ninit_srel\n");
  566.          for (i = 0; i <= datalbl_ndx; i++) {
  567.        if (datalbl[i].name == NULL)    
  568.        {
  569.          fprintf (stderr, "asm_file_end intern err (datalbl)\n");
  570.          exit (0);
  571.        }
  572.            fprintf(file,"%s\t block %d\n",
  573.                  datalbl[i].name,datalbl[i].size);
  574.            cum_size += datalbl[i].size;
  575.      }
  576.          fprintf(file,"\n\tinit\n");
  577.          fprintf(file,"\tLIM  R0,init_srel ;dst\n");
  578.          fprintf(file,"\tLIM  R1,%d ;cnt\n",cum_size);
  579.          fprintf(file,"\tLIM  R2,K%s ;src\n",datalbl[0].name);
  580.          fprintf(file,"\tMOV  R0,R2\n");
  581.          fprintf(file,"\n\tnormal\n");
  582.          datalbl_ndx = -1;
  583.          for (i = 0; i < DATALBL_ARRSIZ; i++)
  584.             datalbl[i].size = 0;
  585.       }    
  586.       fprintf(file,"\n\tend\n");
  587. }
  588.  */
  589.